using NUnit.Framework;
using ValidationFramework.Reflection;

namespace ValidationFramework.Tests.Reflection
{

    public class FieldDescriptorTest
    {
        [RequiredIntRule]
        private static int myStaticField;
        [RequiredIntRule]
        private int myInstanceField;


		[TestFixture]
		public class Constructor
		{
			[Test]
			public void Instance()
			{
				var runtimeTypeHandle = typeof(FieldDescriptorTest).TypeHandle;
				var typeDescriptor = TypeCache.GetType(runtimeTypeHandle);
				Assert.AreEqual(2, typeDescriptor.Fields.Count);
				Assert.AreEqual(runtimeTypeHandle, typeDescriptor.RuntimeTypeHandle);

				const string fieldName = "myInstanceField";
				var fieldDescriptor = typeDescriptor.Fields[fieldName];
				Assert.AreEqual(fieldName, fieldDescriptor.Name);
				Assert.IsFalse(fieldDescriptor.IsStatic);
				Assert.AreEqual(1, fieldDescriptor.Rules.Count);
				Assert.AreEqual(fieldDescriptor, fieldDescriptor.Rules.InfoDescriptor);

				Assert.AreEqual(typeDescriptor.Fields.TypeDescriptor, typeDescriptor);
			}


			[Test]
			public void Static()
			{
				var runtimeTypeHandle = typeof(FieldDescriptorTest).TypeHandle;
				var typeDescriptor = TypeCache.GetType(runtimeTypeHandle);
				Assert.AreEqual(2, typeDescriptor.Fields.Count);
				Assert.AreEqual(runtimeTypeHandle, typeDescriptor.RuntimeTypeHandle);

				const string fieldName = "myStaticField";
				var fieldDescriptor = typeDescriptor.Fields[fieldName];
				Assert.AreEqual(fieldName, fieldDescriptor.Name);
				Assert.IsTrue(fieldDescriptor.IsStatic);
				Assert.AreEqual(1, fieldDescriptor.Rules.Count);
				Assert.AreEqual(fieldDescriptor, fieldDescriptor.Rules.InfoDescriptor);
				Assert.AreEqual(typeDescriptor.Fields.TypeDescriptor, typeDescriptor);

			}
		}

		[TestFixture]
		public class GetValue
		{
			[Test]
			public void Instance()
			{
				var runtimeTypeHandle = typeof(FieldDescriptorTest).TypeHandle;
				var typeDescriptor = TypeCache.GetType(runtimeTypeHandle);
				Assert.AreEqual(2, typeDescriptor.Fields.Count);
				Assert.AreEqual(runtimeTypeHandle, typeDescriptor.RuntimeTypeHandle);

				const string fieldName = "myInstanceField";
				var fieldDescriptor = typeDescriptor.Fields[fieldName];

				var descriptorsTest = new FieldDescriptorTest {myInstanceField = 10};
			    var value = fieldDescriptor.GetValue(descriptorsTest);
				Assert.AreEqual(10, value);
			}


			[Test]
			public void Static()
			{
				var runtimeTypeHandle = typeof(FieldDescriptorTest).TypeHandle;
				var typeDescriptor = TypeCache.GetType(runtimeTypeHandle);
				Assert.AreEqual(2, typeDescriptor.Fields.Count);
				Assert.AreEqual(runtimeTypeHandle, typeDescriptor.RuntimeTypeHandle);

				const string fieldName = "myStaticField";
				var fieldDescriptor = typeDescriptor.Fields[fieldName];
				myStaticField = 10;
				var value = fieldDescriptor.GetValue(null);

				Assert.AreEqual(10, value);
			}
		}


    }
}